package com.mango.coomb.threads.parameter;


import com.mango.coomb.constant.ThreadConst;
import com.mango.coomb.enums.*;

import java.util.Arrays;

public class ThreadParameter {
    public static Long startTime=null;
    public static Long pausedTime= 0L;
    public static Boolean isWriterReadRunning=false;
    public static Boolean isWriterWriteRunning=false;
    public static Boolean isReaderZeroReadRunning=false;
    public static Boolean isReaderNegReadRunning=false;
    public static Boolean isReaderPosReadRunning=false;
    public static Boolean isReaderZeroWriteRunning=false;
    public static Boolean isReaderNegWriteRunning=false;
    public static Boolean isReaderPosWriteRunning=false;
    public static final Object writerReadLock=new Object();
    public static final Object writerWriteLock=new Object();
    public static final Object readerZeroReadLock=new Object();
    public static final Object readerNegReadLock=new Object();
    public static final Object readerPosReadLock=new Object();
    public static final Object readerZeroWriteLock=new Object();
    public static final Object readerNegWriteLock=new Object();
    public static final Object readerPosWriteLock=new Object();
    private static boolean isSafe=true;
    private static Status operationalStatus = Status.NOT_BEGIN;
    private static Modes modeState = Modes.RANDOM;
    private static boolean isHavingData = false;
    private static double totalTimeSpent = 0; // 总耗时
    private static int totalCount = 0; // 总数
    private static int totalCompletionCount = 0; // 完成总数
    private static double processingSpeedCount = 0; // 处理速度
    private static final int[] targetTotalCountArr = new int[3];
    private static final int[] blockingCountArr = new int[4];
    private static final int[] idleCountArr = new int[3];
    private static final int[] notIdleCountArr = new int[3];
    private static final int[] areaCountArr = new int[5];
    private static final int[] speedMultipleArr = new int[2];
    private static final Integer[] writerBufferValueArr = new Integer[ThreadConst.WRITER_BUFFER_COUNT];
    public static final Object[] writerBufferLock=new Object[ThreadConst.WRITER_BUFFER_COUNT];
    public static final Boolean[] isWriterBufferLockedArr =new Boolean[ThreadConst.WRITER_BUFFER_COUNT];
    private static final Integer[] bufferBufferValueArr = new Integer[ThreadConst.BUFFER_BUFFER_MAX_COUNT];
    public static final Object[] bufferBufferLock=new Object[ThreadConst.BUFFER_BUFFER_MAX_COUNT];
    public static final Boolean[] isBufferBufferLockedArr =new Boolean[ThreadConst.BUFFER_BUFFER_MAX_COUNT];
    private static final Integer[] readerPosBufferValueArr = new Integer[ThreadConst.READER_POS_BUFFER_COUNT];
    public static final Object[] readerPosBufferLock=new Object[ThreadConst.READER_POS_BUFFER_COUNT];
    public static final Boolean[] isReaderPosBufferLockedArr =new Boolean[ThreadConst.READER_POS_BUFFER_COUNT];
    private static final Integer[] readerNegBufferValueArr = new Integer[ThreadConst.READER_NEG_BUFFER_COUNT];
    public static final Object[] readerNegBufferLock=new Object[ThreadConst.READER_NEG_BUFFER_COUNT];
    public static final Boolean[] isReaderNegBufferLockedArr =new Boolean[ThreadConst.READER_NEG_BUFFER_COUNT];
    private static final Integer[] readerZeroBufferValueArr = new Integer[ThreadConst.READER_ZERO_BUFFER_COUNT];
    public static final Object[] readerZeroBufferLock=new Object[ThreadConst.READER_ZERO_BUFFER_COUNT];
    public static final Boolean[] isReaderZeroBufferLockedArr =new Boolean[ThreadConst.READER_ZERO_BUFFER_COUNT];

    static {
        areaCountArr[ThreadConst.WRITER_BUFFER_COUNT_NUM]=ThreadConst.WRITER_BUFFER_COUNT;
        areaCountArr[ThreadConst.READER_BUFFER_POS_COUNT_NUM]=ThreadConst.READER_POS_BUFFER_COUNT;
        areaCountArr[ThreadConst.READER_BUFFER_NEG_COUNT_NUM]=ThreadConst.READER_NEG_BUFFER_COUNT;
        areaCountArr[ThreadConst.READER_BUFFER_ZERO_COUNT_NUM]=ThreadConst.READER_ZERO_BUFFER_COUNT;
        Arrays.fill(isWriterBufferLockedArr,false);
        Arrays.fill(isBufferBufferLockedArr,false);
        Arrays.fill(isReaderPosBufferLockedArr,false);
        Arrays.fill(isReaderNegBufferLockedArr,false);
        Arrays.fill(isReaderZeroBufferLockedArr,false);
        Arrays.fill(writerBufferValueArr, null);
        Arrays.fill(bufferBufferValueArr, null);
        Arrays.fill(readerPosBufferValueArr, null);
        Arrays.fill(readerNegBufferValueArr, null);
        Arrays.fill(readerZeroBufferValueArr, null);
        Arrays.fill(writerBufferLock,new Object());
        Arrays.fill(bufferBufferLock,new Object());
        Arrays.fill(readerPosBufferLock,new Object());
        Arrays.fill(readerNegBufferLock,new Object());
        Arrays.fill(readerZeroBufferLock,new Object());
    }

    public static Integer[] getWriterBufferValueArr() {
        return writerBufferValueArr;
    }

    public static Integer[] getBufferBufferValueArr() {
        return bufferBufferValueArr;
    }

    public static Integer[] getReaderPosBufferValueArr() {
        return readerPosBufferValueArr;
    }

    public static Integer[] getReaderNegBufferValueArr() {
        return readerNegBufferValueArr;
    }

    public static Integer[] getReaderZeroBufferValueArr() {
        return readerZeroBufferValueArr;
    }
    public static Integer getWriterBufferValue(int i) {
        return writerBufferValueArr[i];
    }

    public static Integer getBufferBufferValue(int i) {
        return bufferBufferValueArr[i];
    }

    public static Integer getReaderPosBufferValue(int i) {
        return readerPosBufferValueArr[i];
    }

    public static Integer getReaderNegBufferValue(int i) {
        return readerNegBufferValueArr[i];
    }

    public static Integer getReaderZeroBufferValue(int i) {
        return readerZeroBufferValueArr[i];
    }

    public static int getTargetTotalCount(Sign sign) {
        switch (sign) {
            case READER_POS:
                return targetTotalCountArr[ThreadConst.TARGET_POS_TOTAL_COUNT_NUM];
            case READER_NEG:
                return targetTotalCountArr[ThreadConst.TARGET_NEG_TOTAL_COUNT_NUM];
            case READER_ZERO:
                return targetTotalCountArr[ThreadConst.TARGET_ZERO_TOTAL_COUNT_NUM];
            default:
                return -1;
        }
    }

    public static int getBlockingCount(ThreadClass threadClass, Actions actions) {
        switch (threadClass) {
            case WRITER:
                switch (actions) {
                    case THREAD_WRITE:
                        return blockingCountArr[ThreadConst.WRITER_WRITE_BLOCKING_COUNT_NUM];
                    case THREAD_READ:
                        return blockingCountArr[ThreadConst.WRITER_READ_BLOCKING_COUNT_NUM];
                    default:
                        return -1;
                }
            case READER:
                switch (actions) {
                    case THREAD_WRITE:
                        return blockingCountArr[ThreadConst.READER_WRITE_BLOCKING_COUNT_NUM];
                    case THREAD_READ:
                        return blockingCountArr[ThreadConst.READER_READ_BLOCKING_COUNT_NUM];
                    default:
                        return -1;
                }
            default:
                return -1;
        }
    }

    public static int getIdleOrNotCount(AreaClass areaClass, boolean isIdle) {
        switch (areaClass) {
            case WRITER:
                return isIdle ? idleCountArr[ThreadConst.WRITER_IDLE_OR_NOT_COUNT_NUM]
                        : notIdleCountArr[ThreadConst.WRITER_IDLE_OR_NOT_COUNT_NUM];
            case BUFFER:
                return isIdle ? idleCountArr[ThreadConst.BUFFER_IDLE_OR_NOT_COUNT_NUM]
                        : notIdleCountArr[ThreadConst.BUFFER_IDLE_OR_NOT_COUNT_NUM];
            case READER:
                return isIdle ? idleCountArr[ThreadConst.READER_IDLE_OR_NOT_COUNT_NUM]
                        : notIdleCountArr[ThreadConst.READER_IDLE_OR_NOT_COUNT_NUM];
            default:
                return -1;
        }
    }

    public static int getAreaCount(AreaClass areaClass, Sign sign) {
        if (sign == null) {
            switch (areaClass) {
                case WRITER:
                    return areaCountArr[ThreadConst.WRITER_BUFFER_COUNT_NUM];
                case BUFFER:
                    return areaCountArr[ThreadConst.BUFFER_BUFFER_COUNT_NUM];
                default:
                    return -1;
            }
        } else {
            switch (sign) {
                case READER_NEG:
                    return areaCountArr[ThreadConst.READER_BUFFER_NEG_COUNT_NUM];
                case READER_POS:
                    return areaCountArr[ThreadConst.READER_BUFFER_POS_COUNT_NUM];
                case READER_ZERO:
                    return areaCountArr[ThreadConst.READER_BUFFER_ZERO_COUNT_NUM];
                default:
                    return -1;
            }
        }
    }

    public static int getSpeedMultiple(ThreadClass threadCLass) {
        switch (threadCLass) {
            case WRITER:
                return speedMultipleArr[ThreadConst.WRITER_SPEED_Multiple_NUM];
            case READER:
                return speedMultipleArr[ThreadConst.READER_SPEED_Multiple_NUM];
            default:
                return -1;
        }
    }

    public static void setModeState(Modes modesState) {
        ThreadParameter.modeState = modesState;
    }


    public static boolean isHavingData() {
        return isHavingData;
    }

    public static void setIsHavingData(boolean isHavingData) {
        ThreadParameter.isHavingData = isHavingData;
    }

    public static double getTotalTimeSpent() {
        return totalTimeSpent;
    }

    public static void setTotalTimeSpent(double totalTimeSpent) {
        ThreadParameter.totalTimeSpent = totalTimeSpent;
    }

    public static int getTotalCount() {
        return totalCount;
    }

    public static void setTotalCount(int totalCount) {
        ThreadParameter.totalCount = totalCount;
    }

    public static int getTotalCompletionCount() {
        return totalCompletionCount;
    }

    public static void setTotalCompletionCount(int totalCompletionCount) {
        ThreadParameter.totalCompletionCount = totalCompletionCount;
    }

    public static double getProcessingSpeedCount() {
        return processingSpeedCount;
    }

    public static void setProcessingSpeedCount(double processingSpeedCount) {
        ThreadParameter.processingSpeedCount = processingSpeedCount;
    }

    public static int[] getTargetTotalCountArr() {
        return targetTotalCountArr;
    }

    public static int[] getBlockingCountArr() {
        return blockingCountArr;
    }

    public static int[] getIdleCountArr() {
        return idleCountArr;
    }

    public static int[] getNotIdleCountArr() {
        return notIdleCountArr;
    }

    public static int[] getAreaCountArr() {
        return areaCountArr;
    }

    public static int[] getSpeedMultipleArr() {
        return speedMultipleArr;
    }

    public static Status getOperationalStatus() {
        return operationalStatus;
    }

    public static void setOperationalStatus(Status operationalStatus) {
        ThreadParameter.operationalStatus = operationalStatus;
    }

    public static Modes getModeState() {
        return modeState;
    }

    public static boolean isSafe() {
        return isSafe;
    }

    public static void setIsSafe(boolean isSafe) {
        ThreadParameter.isSafe = isSafe;
    }

}
